package com.gzedu.frame.logic.net.json;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

/**
 * <font color="#0000FF"> 
*<p>Json 数据解析器</p></font>
* @Title: JsonParser.java
* @Package com.gzedu.frame.logic.net.json
* @company:		广州远程教育中心有限公司
* @author :		戴俊林
* @date 2012-8-28 上午10:54:01
* @version V1.0
 */
public class JsonParser {
	
	private String requestMethod;
	
	/**
	 * 初始化接口请求方式
	 * @param requestMethodType		接口数据提交方式 POST/GET
	 */
	public JsonParser(String requestMethodType){
		this.requestMethod=requestMethodType;
	}
	
	/**
	 * 
	*<p>通过网络接口获取List<Map<String, String>>格式数据</p>
	* @param @param url
	* @param @param formMap
	* @param @return    
	* @return List<Map<String,String>>    
	* @throws
	* @see {@link #getJsonInfo(String, Map)} 获取网络数据
	 */
	@SuppressWarnings("unchecked")
	public List<Map<String, String>> getJsonDate(String url,Map<String, String> formMap) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		List<Map<String, Object>> listInfo = getJsonInfo(url, formMap);
		if (listInfo != null) {
			for (Map<String, Object> mapInfo : listInfo) {
				Map<String, String> map = new HashMap<String, String>();
				Set<String> set = mapInfo.keySet();
				Iterator<String> iter = set.iterator();
				while (iter.hasNext()) {
					String key = iter.next();
					Object object = mapInfo.get(key);
					if (object instanceof List) {
						List<Map<String, String>> viewList = (List<Map<String, String>>) object;
						if (viewList != null && viewList.size() > 0) {
							list = viewList;
						}
					} else if (object instanceof String) {
						map.put(key, (String) object);
					}
				}
				list.add(map);
			}
		}
		return list;
	}

	/**
	 * 
	*<p>获取网络接口数据</p><br>
	*{@link #getUrl} 组装接口地址(接口域名+接口参数)
	* @param @param httpUrl	接口域名
	* @param @param map		接口参数
	* @param @return    
	* @return List<Map<String,Object>>    
	* @throws
	* @see {@link #inputStream2Byte(InputStream)} 
	 */
	private List<Map<String, Object>> getJsonInfo(String httpUrl,
			Map<String, String> map) {
		List<Map<String, Object>> listjsonString = null;
		String path = getUrl(httpUrl, map);
		Log.i("接口地址", path);
		URL url;
		try {
			url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5 * 1000);
			conn.setRequestMethod(requestMethod);
			if (conn.getResponseCode() == 200) {
				InputStream is = conn.getInputStream();
				byte[] data = inputStream2Byte(is);
				String json = new String(data);
				listjsonString = jsonString2List(json);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listjsonString;
	}
	
	/**
	 * 
	*<p>组装url接口地址</p>
	* @param @param httpUrl
	* @param @param parameters
	* @param @return    
	* @return String    
	* @throws
	 */
	private String getUrl(String httpUrl, Map<String, String> parameters) {
		StringBuffer params = new StringBuffer();
		try {
			for (Iterator<Entry<String, String>> iter = parameters.entrySet()
					.iterator(); iter.hasNext();) {
				Entry<String, String> element = iter.next();
				params.append(element.getKey().toString());
				params.append("=");
				params.append(URLEncoder.encode(element.getValue().toString(),
						"GBK"));
				params.append("&");
			}
			if (params.length() > 0) {
				params = new StringBuffer("?").append(params
						.deleteCharAt(params.length() - 1));
			}
		} catch (Exception e) {
		}
		return httpUrl + params.toString();
	}

	/**
	 * 
	*<p>将json字符串转成List</p>
	* @param @param jsonString
	* @param @return    
	* @return List<Map<String,Object>>    
	* @throws
	* @see {@link #jsonArray2List(JSONArray)}
	 */
	@SuppressWarnings("unchecked")
	private List<Map<String, Object>> jsonString2List(String jsonString) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			Iterator<String> iterOut = jsonObject.keys();
			while (iterOut.hasNext()) {
				String keyOUt = iterOut.next();
				Object object = jsonObject.get(keyOUt);
				if (object instanceof JSONObject) {
					JSONObject jsonObjectOne = (JSONObject) object;
					Iterator<String> iter = jsonObjectOne.keys();
					String key = null;
					while (iter.hasNext()) {
						key = iter.next();
						Object objectOne = jsonObjectOne.get(key);
						Map<String, Object> map = new HashMap<String, Object>();
						if (objectOne instanceof String) {
							String value = (String) objectOne;
							map.put(key, value);
						} else if (objectOne instanceof Boolean) {
							Boolean value = (Boolean) objectOne;
							map.put(key, value.toString());
						} else if (objectOne instanceof Integer) {
							Integer value = (Integer) objectOne;
							map.put(key, value.toString());
						} else if (objectOne instanceof JSONObject) {
							JSONObject value = (JSONObject) objectOne;
							map.put(key, value.toString());
						} else if (objectOne instanceof JSONArray) {
							JSONArray value = (JSONArray) objectOne;
							List<Map<String, Object>> listInSide = jsonArray2List(value);
							map.put(key, listInSide);
						} else if (objectOne instanceof Date[]) {
						}
						list.add(map);
					}
				} else if (object instanceof String
						|| object instanceof Integer) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put(keyOUt, object);
					list.add(map);
				} else if (object instanceof JSONArray) {
					JSONArray value = (JSONArray) object;
					List<Map<String, Object>> listInSide = jsonArray2List(value);
					for (Map<String, Object> map : listInSide) {
						list.add(map);
					}
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 
	*<p>将JSONArray转换成List<Map<String, Object>></p>
	* @param @param JsonArray
	* @param @return    
	* @return List<Map<String,Object>>    
	* @throws
	 */
	@SuppressWarnings("unchecked")
	private List<Map<String, Object>> jsonArray2List(JSONArray JsonArray) {
		List<Map<String, Object>> listJson = new ArrayList<Map<String, Object>>();
		Map<String, Object> stringMap = new HashMap<String, Object>();
		String key = null;
		for (int i = 0; i < JsonArray.length(); i++) {
			JSONObject JsonObjectInside;
			try {
				Object object = (Object) JsonArray.get(i);
				if (object instanceof JSONObject) {
					JsonObjectInside = (JSONObject) object;
					Iterator<String> iterInside = JsonObjectInside.keys();
					Map<String, Object> map = new HashMap<String, Object>();
					while (iterInside.hasNext()) {
						key = iterInside.next();
						map.put(key, JsonObjectInside.getString(key));
					}
					listJson.add(map);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		if (stringMap != null && stringMap.size() > 0) {
			listJson.add(stringMap);
		}
		return listJson;
	}

	/**
	 * 
	*<p>将输入流转成字节数组</p>
	* @param @param inputStream
	* @param @return
	* @param @throws Exception    
	* @return byte[]    
	* @throws
	 */
	private static byte[] inputStream2Byte(InputStream inputStream) throws Exception {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inputStream.read(buffer)) != -1) {
			bout.write(buffer, 0, len);
		}
		bout.close();
		inputStream.close();
		return bout.toByteArray();
	}

}
